home *** CD-ROM | disk | FTP | other *** search
/ Scene Storm / Scene Storm - Volume 1.iso / coding / c / getfreespace / mcfree.c < prev    next >
C/C++ Source or Header  |  1995-09-01  |  6KB  |  156 lines

  1. /* McFree v2.1 by Mack Lifeguard. This program is hereby placed in the
  2.  * public domain. You can use it for whatever purpose you like, just don't
  3.  * hold me responsible for any problems it may cause. */
  4.  
  5. /*  This program is a very simple but interesting example of how you can
  6.  *  use the AmigaDOS libraries to cut your executables' size in half. When
  7.  *  compiling this program be sure to link with "amiga.lib", since the
  8.  *  sprintf() function in amiga.lib uses the internal ROM's printf() function.
  9.  *  Thus, you're program is now 3k smaller! Be warned, some features of the
  10.  *  regular sprintf() do not work 100% on the amiga.lib sprintf(). Mainly you
  11.  *  are limited to only 140 bytes of the final outputting string (anything
  12.  *  above that and you get an instant guru), and you can't use the "%.*"
  13.  *  qualifier. But for small programs like these, the sprintf() in amiga.lib
  14.  *  works great. Again, you must include "amiga.lib" in your LINK list. If you
  15.  *  are using SAS C, then just go to scopts and enter "amiga.lib" in the
  16.  *  Libraries/Objects section under the Link gadget. */
  17.  
  18. /* Many more space-saving techniques are used. Primarily they are
  19.  * compiling options. I won't go into detail on how they work, but you can
  20.  * see for yourself the settings in the included SCOPTIONS file. */
  21.  
  22. /* If you compile this program using standard SAS C options, you will get
  23.  * an executable of size 6619 bytes. Using the included SCOPTIONS file you
  24.  * will get a filesize of 1688. A considerable difference! */
  25.  
  26. #include <stdio.h>
  27. #include <dos.h>
  28. #include <string.h>
  29. #include <stdlib.h>
  30. #include <proto/dos.h> /* We use pragmas, so no need for opening libraries.
  31.                         * The pragmas in <proto/dos.h> automatically call
  32.                         * each dos function directly. */
  33.  
  34. void errorf(char *text);
  35. char out[80], *p;
  36.  
  37. void main(int argc,char *argv[])
  38. {
  39.  
  40. /* We use the external argc variable to gauge the number of arguments. */
  41. /* Argc always returns at least a value of 1 (one). */
  42.  
  43. __aligned struct InfoData info;  /* Just to be safe, use a 4 byte boundary. */
  44. int x,size=0;
  45. BPTR lock;
  46.  
  47. for (p=out; p<&out[80]; p++)
  48.   *p=NULL;
  49.  
  50. Write(Output(), "\nMcFree v2.1 by Mack Lifeguard\n\n",32);
  51.  
  52. /*  By using the Output() device, in combination with Write(), the program
  53.  *  becomes considerably smaller. Instead of using C's printf(), which takes
  54.  *  up an additional 3k. */
  55.  
  56.  
  57. if (argc==1)
  58.   Write(Output(),"USAGE: McFree <Volume1> ... [Volume29]\n\n",40);
  59.  
  60. /* As mentioned earlier, if there is only one argument (argc==1), then the
  61.  * user did not input any parameters, so we send a message and exit. */
  62.  
  63.  
  64. for (x=1;x<argc;x++)
  65. {
  66.  
  67.  /* OK, so the user entered some arguments, lets check to see if they
  68.   *  are valid I/O devices, then we calculate their available free
  69.   *  storage. NOTE: This is an approximation based on number of blocks
  70.   *  used.  The exact free storage can only be calculated by going in and
  71.   *  adding up each individual file size.  By using blocks to calculate,
  72.   *  you may be off by a few bytes or so, but you can get the information
  73.   *  in a few CPU cycles, without scanning the entire device.  */
  74.  
  75.  
  76.   /* Now, lets check to see if we can get a Lock() on the device. */
  77.  
  78.   if (  (lock=Lock (argv[x], ACCESS_READ))==NULL)
  79.     errorf(argv[x]); /* No deal, lets send an error message and continue. */
  80.   else
  81.     {
  82.  
  83.     /* Target is locked! But we're not through yet, lets be extra safe and
  84.      * check to see if we can get a succesful Info() on it. */
  85.  
  86.     if ( !Info(lock,&info) )
  87.       errorf(argv[x]); /* We send an error message but continue loop. */
  88.     else
  89.       {
  90.  
  91.       /*  Here is the main calculation part of the program. The Info()
  92.        *  function from Amigados has filled our file I/O structure.
  93.        *  Remember?  The one we aligned on a 4 byte boundary?  OK, so now
  94.        *  we simply do some multiplication and substraction.  The labels
  95.        *  should be self-explanatory, we are merely subtracting the used
  96.        *  blocks from the available blocks.  Then we just multiply the
  97.        *  result by the number of bytes in each block.  Keep in mind, not
  98.        *  all devices have the same number of bytes per block!  */
  99.  
  100.       size=(info.id_NumBlocks - info.id_NumBlocksUsed) * info.id_BytesPerBlock;
  101.  
  102.       sprintf(out, "Drive %s has %ld bytes free. \n",argv[x],size);
  103.  
  104.       Write(Output(), out, strlen(out));
  105.       }
  106.       UnLock(lock);  /*  Always Unlock() what you Lock. If you don't, then
  107.                       *  you will get an "Object In Use" error the next
  108.                       *  time you try to access a locked file/device.  */
  109.     }
  110. }  /* End of main for loop. */
  111.  
  112. _exit(0);    /* Always exit with 0 on success. */
  113.  
  114.       /* NOTE: I used the special _exit() function (notice the
  115.        * underscore) because the normal exit() function frees memory and
  116.        * closes files for you.  However, since we are not using standard C
  117.        * I/O, that is, we are using AmigaDOS functions from libraries,
  118.        * then we really don't need the features of the regular exit().
  119.        * The special _exit() simply returns control to the operating
  120.        * system, without freeing memory or closing files, WE are expected
  121.        * to do that.  I use this function because it saves about 2k.  */
  122. }
  123.  
  124. void errorf(char *text)
  125. {
  126. sprintf(out, ">>Error reading volume: \"%.20s\"\n",text);
  127.  
  128. /* Notice how I used the special sprintf() quailifier "%.20s", this
  129.  * gurantees that a MAXIMUM of 20 characters will be used in the final
  130.  * string. Any characters after 20 are simply ignored in the conversion.
  131.  * This is just a safeguard against breaking the 140 byte limit on the
  132.  * special amiga.lib sprintf() function. If we were using the standard
  133.  * C sprintf() then there wouldn't be any need for this check. */
  134.  
  135. Write(Output(), out, strlen(out) );
  136. }
  137.  
  138.  
  139.  
  140. /*
  141.                                CONTACT INFO
  142.                                =-=-=-=-=-=-
  143.  
  144. If you have any questions, bug reports, suggestiongs, you can contact me at
  145. the following:
  146.  
  147. Hangar 18: (713) 488-3055
  148. International Chaos: (713) 999-3640
  149. Complex Corrosion: (612) 773-0522    [4 nodes]
  150. Danse Macabre: (713) 324-1165
  151.  
  152. -Mack Lifeguard/Dual Crew-Shining
  153.  
  154. */
  155.  
  156.